Http Client

Descripcion

Como utilizar HttpClient para hacer peticiones HTTP desde Angular

Código de ejemplo
Preparacion

Primero en el archivo app.module.ts tenemos que importar el modulo HttpClientModule:

import { HttpClientModule } from '@angular/common/http';

el código del archivo app.module.ts quedaría asi:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';

import { AppComponent } from './app.component';
import { HttpViewComponent } from './http-view/http-view.component';

@NgModule({
  declarations: [
    AppComponent,
    HttpViewComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
Metodo

http-view.service.ts

Para utilizar el HttpClient vamos a usar un componente y un servicio

En el servicio (http-view.service.ts) realizamos el siguiente import:

import { HttpClient } from '@angular/common/http';

En el constructor declaramos una variable HttpClient:

constructor(private http:HttpClient) { }

Y definimos una interfaz, que será la que nos indique la estructura de la informacion que vamos a recibir

export interface messageRequest {
  userId: number;
  id:number;
  title:string;
  completed:boolean;
}

ya que recibiremos una peticion json que será tal que así:

{
    "userId": 1,
    "id": 1,
    "title": "delectus aut autem",
    "completed": false
  }

Y para terminar definimos una funcion getInfo que usará el objeto HttpClient para hacer la solicitud:

getInfo(){
    return this.http.get<messageRequest[]>("https://jsonplaceholder.typicode.com/todos")
}

El metodo http.get tiene que tener un tipo de datos, en este caso le estamos pasando messageRequest[], osea un array de la interfaz que creamos justo antes, esto quiere decir que podremos almacenar varios objetos del tipo messageRequest

El unico parametro que pasamos despues a la funcion get es la direccion a donde realizará la peticion

El archivo del servicio, http-view.service.ts, quedaría asi:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

export interface messageRequest {
  userId: number;
  id:number;
  title:string;
  completed:boolean;
}

@Injectable({
  providedIn: 'root'
})
export class HttpViewService {

  constructor(private http:HttpClient) { }

  getInfo(){
    return this.http.get<messageRequest[]>("https://jsonplaceholder.typicode.com/todos")
  }
}

http-view.component.ts

En el archivo del componente http-view.component.ts, primero creamos una variable de tipo messageRequest[]; que será donde se almacenen los datos que devuelva la peticion

messageObject: messageRequest[];

A continuacion en el constructor creamos una variable httpView de tipo HttpViewService para utilizar nuestro servicio en el componente

constructor( private httpView: HttpViewService )

Y por ultimo en la funcion ngOnInit usamos nuestro servicio para llamar a la funcion getInfo() que nos devolverá un Observavle con el que podremos obtener los datos de la peticion y almacenarlos en nuestra variable messageObject

this.httpView.getInfo().subscribe(data => this.messageObject = data)

El codigo del componente http-view.component.ts quedaría tal que asi:

import { Component, OnInit } from '@angular/core';
import { messageRequest, HttpViewService } from './http-view.service';

@Component({
  selector: 'app-http-view',
  templateUrl: './http-view.component.html',
  styleUrls: ['./http-view.component.css']
})
export class HttpViewComponent implements OnInit {

  messageObject: messageRequest[];

  constructor( private httpView: HttpViewService ) {
  }

  ngOnInit(): void {
    this.httpView.getInfo().subscribe(data => this.messageObject = data)
  }

}

Una manera alternativa (en verdad es la recomendada), de definir el subscribe es la siguiente:

this.httpView
      .getInfo()
      .subscribe({
        next: (data) => (this.messageObject = data),
        error: (error) => console.log(error),
        complete: () => console.log("complete")
      });

Esta implementación nos permite coger el valor de la respuesta next, del error error y de finalización de la solicitud complete

http-view.component.html

Y por ultimo solo tenemos que mostrar la información en nuestro template http-view.component.html, usaremos el array messageObject para mostrar todos los datos que ha devuelto la solicitud, en este caso los mostramos en una tabla usando el ngFor:

<table border="solid">
    <tr *ngFor="let message of messageObject">
        <td>{{message.id}}</td>
        <td>{{message.title}}</td>
    </tr>

</table>

La salida de la aplicacion sería asi:

Manejar errores

Para manejar los errores que puede dar una solicitud lo hacemos de la siguiente manera:

  getInfo(){
    return this.http.get<messageRequest[]>("http://127.0.0.1:8080/api/members")
    .pipe(catchError(this.errorHandler))
  }

  errorHandler(error: HttpErrorResponse){
      if (error.status === 0) {
        console.error("Cannot connect");
      } else {
        console.error("Server Error");
      }

      return throwError(
        () => new Error("Error on request")
      );
    }

Al final de la funcion get encadenamos el siguiente pipe:

.pipe(catchError(this.errorHandler))

En este caso definimos una funcion errorHandler para gestionar los errores

Dentro de la funcion errorHandler comprobamos que tipo de error se produce, si es 0 quiere decir que es un error de que el cliente no se ha podido conectar, si es distinto de 0 es un error del servidor y el numero en si indica el tipo de error, despues el metodo lanza un error indicando que algo ha salido mal (independientemente de que haya sido problema del cliente o del servidor)

Manejar códigos de respuesta

El método anterior nos permite manejar los errores en el servicio, pero si queremos tener acceso a los codigos de error que devuelve la petición tenemos que hacerlo de la siguiente manera:

En el servicio añadimos la opción {observe: 'response'} en la solicitud, y no realizamos el pipe como hacíamos antes.

Y ahora al hacer el subscribe podemos acceder a la propiedad status de los objetos, que contiene el código de la solicitud

Tags

Http Client | request | solicitud | Angular